//
//  YTKRequest+RAC.m
//  ADKit
//
//  Created by duzexu on 2017/11/29.
//  Copyright © 2017年 duzexu. All rights reserved.
//

#import "YTKRequest+RAC.h"
#import "ADKitHeaders.h"

@implementation YTKRequest (RAC)

- (RACSignal *)rac_start {
    return [self rac_startWithReflectClass:nil];
}

- (RACSignal *)rac_startWithReflectClass:(Class)cls {
    YTKNetworkConfig *config = [YTKNetworkConfig sharedConfig];
    if (config.debugLogEnabled) {
        ADLog(@"\n---------[Request Start]--------\n %@ %@",self.requestUrl,self.requestArgument);
    }
    @weakify(self);
    RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        @strongify(self);
        self.resumableDownloadProgressBlock = ^(NSProgress *progress) {
            [(id<ADSubscriber>)subscriber sendProgress:progress.fractionCompleted];
        };
        @weakify(self);
        [self startWithCompletionBlockWithSuccess:^(__kindof YTKBaseRequest * _Nonnull request) {
            if (config.debugLogEnabled) {
                ADLog(@"\n----------[Success Response]-----------\n %@",request);
            }
            @strongify(self);
            [self successPraserWithRequest:request class:cls subscriber:subscriber];
        }
                                          failure:^(__kindof YTKBaseRequest * _Nonnull request) {
                                              if (config.debugLogEnabled) {
                                                  ADLogError(@"\n----------[Failure Response]-----------\n %@ \n%@",request,request.error);
                                              }
                                              @strongify(self);
                                              [self failurePraserWithRequest:request subscriber:subscriber];
                                          }];
        return [RACDisposable disposableWithBlock:^{
            @strongify(self);
            [self stop];
        }];
    }];
    signal.object = self;
    return [signal replayLazily];
}

- (void)successPraserWithRequest:(YTKBaseRequest *)request class:(Class)cls subscriber:(id<ADSubscriber>)subscriber {
    id result = [self dataWithRequest:request];
    if (cls) {
        if ([result isKindOfClass:NSDictionary.class]) {
            NSDictionary *parsedObject = [cls yy_modelWithJSON:result];
            if (parsedObject) {
                [subscriber sendNext:parsedObject];
                [subscriber sendCompleted];
            }else{
                [subscriber sendError:[self _dataError]];
            }
        }else if ([result isKindOfClass:NSArray.class]) {
            NSArray *parsedObject = [NSArray yy_modelArrayWithClass:cls json:result];
            if (parsedObject) {
                [subscriber sendNext:parsedObject];
                [subscriber sendCompleted];
            }else{
                [subscriber sendError:[self _dataError]];
            }
        }else if([result isKindOfClass:[NSError class]]){
            [subscriber sendError:result];
        }else{
            [subscriber sendNext:nil];
            [subscriber sendCompleted];
        }
    }else{
        if([result isKindOfClass:[NSError class]]){
            [subscriber sendError:result];
        }else if (result) {
            [subscriber sendNext:result];
            [subscriber sendCompleted];
        }else{
            [subscriber sendNext:nil];
            [subscriber sendCompleted];
        }
    }
}

- (void)failurePraserWithRequest:(YTKBaseRequest *)request subscriber:(id<ADSubscriber>)subscriber {
    [subscriber sendError:[self errorWithRequest:request]];
}

#pragma mark - ADRequestPraser

- (id)dataWithRequest:(YTKBaseRequest *)request {
    return request.responseObject;
}

- (NSError *)errorWithRequest:(YTKBaseRequest *)request {
    NSMutableDictionary *userInfo = @{}.mutableCopy;
    [userInfo setValue:request.error forKey:ADHTTPServiceErrorKey];
    return [NSError errorWithDomain:ADNetConnectError code:request.error.code userInfo:userInfo];
}

#pragma mark - Error Handling
- (NSError *)_dataError {
    return [NSError errorWithDomain:ADNetDataParseError code:0 userInfo:nil];
}

- (RACSignal *)rac_origin_start {
    YTKNetworkConfig *config = [YTKNetworkConfig sharedConfig];
    if (config.debugLogEnabled) {
        ADLog(@"\n---------[Request Start]--------\n %@ %@",self.requestUrl,self.requestArgument);
    }
    @weakify(self);
    RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
        @strongify(self);
        self.resumableDownloadProgressBlock = ^(NSProgress *progress) {
            [(id<ADSubscriber>)subscriber sendProgress:progress.fractionCompleted];
        };
        [self startWithCompletionBlockWithSuccess:^(__kindof YTKBaseRequest * _Nonnull request) {
            if (config.debugLogEnabled) {
                ADLog(@"\n----------[Success Response]-----------\n %@",request);
            }
            [subscriber sendNext:request];
        }
                                          failure:^(__kindof YTKBaseRequest * _Nonnull request) {
                                              if (config.debugLogEnabled) {
                                                  ADLogError(@"\n----------[Failure Response]-----------\n %@ \n%@",request,request.error);
                                              }
                                              [subscriber sendNext:request];
                                          }];
        return [RACDisposable disposableWithBlock:^{
            [self stop];
        }];
    }];
    signal.object = self;
    return [signal replayLazily];
}

@end
